#include "Framebuffer.h"

Framebuffer::Framebuffer()
{

}
Framebuffer::~Framebuffer()
{

}

int Framebuffer::Init()
{
    int fd = open("/dev/fb0", O_RDWR);
    if(fd == -1)
    {
        ERROR("open /dev/fb0 error");
        return -1;
    }
    iFd = fd;
    return 0;
}

int Framebuffer::getFramebufferinfo()
{
    // struct fb_fix_screeninfo finfo;  
    // if (ioctl(iFd, FBIOGET_FSCREENINFO, &finfo))
    // {
    //     ERROR("Error reading fixed information");
    // }
    
    struct fb_var_screeninfo vinfo;
    if (ioctl(iFd, FBIOGET_VSCREENINFO, &vinfo))
    {
        ERROR("Error reading variable information");
        return -1;
    }

    /* 打印获取的屏幕信息 */
    // printf("The mem is :%d\n", finfo.smem_len);
    // printf("The line_length is :%d\n", finfo.line_length);
    // printf("The xres is :%d\n", vinfo.xres);
    // printf("The yres is :%d\n", vinfo.yres);
    printf("The xres_virtual is :%d\n", vinfo.xres_virtual);
    printf("The yres_virtual is :%d\n", vinfo.yres_virtual);
    printf("bits_per_pixel is :%d\n", vinfo.bits_per_pixel);
    printf("Red:   offset = %2d, length = %2d\n", vinfo.red.offset, vinfo.red.length);
    printf("Green: offset = %2d, length = %2d\n", vinfo.green.offset, vinfo.green.length);
    printf("Blue:  offset = %2d, length = %2d\n", vinfo.blue.offset, vinfo.blue.length);
    printf("Alpha: offset = %2d, length = %2d\n", vinfo.transp.offset, vinfo.transp.length);

    iHeight = vinfo.yres_virtual;
    iWidth = vinfo.xres_virtual;
    rgb_type = vinfo.bits_per_pixel / 8;
    screen_size = vinfo.xres_virtual * vinfo.yres_virtual * (rgb_type);

    fbMapMem = (unsigned char*)mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, iFd, 0);

    if (fbMapMem == MAP_FAILED)
    {
        ERROR("mmap failed");
        return -1;
    }
    return 0;
}

void Framebuffer::display_rgb_to_framebuffer(unsigned char* rgb_data,int height,int width)
{
    int x, y;
    int fb_bytes_per_pixel = rgb_type;     // framebuffer中每个像素的字节数
    int rgb_bytes_per_pixel = 3;           // RGB数据中每个像素的字节数 (通常为3字节)

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            // 计算 framebuffer 的目标位置
            int fb_offset = (y * iWidth + x) * fb_bytes_per_pixel;
            // 计算 rgb_data 的源位置
            int rgb_offset = (y * width + x) * rgb_bytes_per_pixel;
            
            fbMapMem[fb_offset] = rgb_data[rgb_offset];             // R
            fbMapMem[fb_offset + 1] = rgb_data[rgb_offset + 1];     // G
            fbMapMem[fb_offset + 2] = rgb_data[rgb_offset + 2];     // B

            // 假设 framebuffer 是32位的（即4字节），并且顺序是BGRA（大部分情况下）
            // fbMapMem[fb_offset] = rgb_data[rgb_offset + 2];      // B
            // fbMapMem[fb_offset + 1] = rgb_data[rgb_offset + 1];  // G
            // fbMapMem[fb_offset + 2] = rgb_data[rgb_offset];      // R
            // fbMapMem[fb_offset + 3] = 0xFF;                      // A (Alpha通道，设置为255) 注意：这里没有 Alpha 通道，所以可以忽略 fb_ptr[fb_offset + 3]，如果需要也可以设置为 0xFF 或 0x00
        }
    }
    
}

int Framebuffer::closeFramebuffer()
{
    if(fbMapMem)
    {
        munmap(fbMapMem, screen_size);
        fbMapMem = nullptr;
    }
    
    close(iFd);
    
    Print_GREEN("关闭设备framebuffer success");

    return 0;
}